#!/usr/bin/env python3
"""
Frontend Deployment Script for AI-Powered SSH Terminal
Handles various deployment scenarios and optimizations
"""

import os
import sys
import shutil
import subprocess
import argparse
import json
from pathlib import Path
import gzip
import mimetypes

def create_nginx_config(domain, ssl=False):
    """Create Nginx configuration for the frontend"""
    template = """
server {{
    listen {port};
    server_name {domain};
    
    {ssl_config}
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript 
               application/javascript application/xml+rss 
               application/json;
    
    # Static files with caching
    location /static/ {{
        alias /var/www/ai-terminal/static/;
        expires 1y;
        add_header Cache-Control "public, immutable";
        
        # Pre-compressed files
        location ~* \\.js$ {{
            gzip_static on;
            add_header Content-Encoding gzip;
        }}
        
        location ~* \\.css$ {{
            gzip_static on;
            add_header Content-Encoding gzip;
        }}
    }}
    
    # WebSocket proxy
    location /ws/ {{
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # WebSocket timeouts
        proxy_read_timeout 86400;
        proxy_send_timeout 86400;
        proxy_connect_timeout 5;
    }}
    
    # API proxy
    location /api/ {{
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }}
    
    # Main application
    location / {{
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }}
    
    # Health check
    location /health {{
        access_log off;
        return 200 "healthy\\n";
        add_header Content-Type text/plain;
    }}
}}
"""
    
    port = "443 ssl http2" if ssl else "80"
    ssl_config = ""
    
    if ssl:
        ssl_config = f"""
    ssl_certificate /etc/ssl/certs/{domain}.crt;
    ssl_certificate_key /etc/ssl/private/{domain}.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    
    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;
    """
    
    return template.format(
        port=port,
        domain=domain,
        ssl_config=ssl_config
    )

def optimize_static_files(static_dir):
    """Optimize static files for production"""
    print(f"🔧 Optimizing static files in {static_dir}")
    
    # Create static directory if it doesn't exist
    static_path = Path(static_dir)
    static_path.mkdir(exist_ok=True)
    
    # Copy main HTML file to static
    html_source = Path("ai-terminal.html")
    if html_source.exists():
        shutil.copy2(html_source, static_path / "index.html")
        print("✓ Copied main HTML file")
    
    # Pre-compress files
    compress_files = [
        "index.html",
        "*.js",
        "*.css",
        "*.json"
    ]
    
    for pattern in compress_files:
        for file_path in static_path.glob(pattern):
            if file_path.is_file():
                compress_file(file_path)

def compress_file(file_path):
    """Compress individual file with gzip"""
    try:
        with open(file_path, 'rb') as f_in:
            with gzip.open(f"{file_path}.gz", 'wb') as f_out:
                shutil.copyfileobj(f_in, f_out)
        
        # Check compression ratio
        original_size = file_path.stat().st_size
        compressed_size = Path(f"{file_path}.gz").stat().st_size
        ratio = (1 - compressed_size / original_size) * 100
        
        print(f"✓ Compressed {file_path.name}: {ratio:.1f}% smaller")
        
    except Exception as e:
        print(f"❌ Failed to compress {file_path}: {e}")

def create_docker_config():
    """Create Docker configuration for frontend deployment"""
    dockerfile = """
FROM nginx:alpine

# Copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Copy static files
COPY static/ /var/www/ai-terminal/static/
COPY ai-terminal.html /var/www/ai-terminal/

# Create directories
RUN mkdir -p /var/log/nginx /var/cache/nginx

# Set permissions
RUN chown -R nginx:nginx /var/www/ai-terminal /var/log/nginx /var/cache/nginx

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
    CMD curl -f http://localhost/health || exit 1

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]
"""
    
    docker_compose = """
version: '3.8'

services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile.frontend
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./ssl:/etc/ssl/certs:ro
      - ./nginx-logs:/var/log/nginx
    environment:
      - NGINX_HOST=terminal.company.com
      - NGINX_PORT=80
    restart: unless-stopped
    depends_on:
      - backend
      
  backend:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - ./models:/app/models
      - ./data:/app/data
    environment:
      - AI_TERMINAL_ENV=production
    restart: unless-stopped
"""
    
    return dockerfile, docker_compose

def setup_cdn_fallback():
    """Setup CDN fallback in HTML"""
    html_file = Path("ai-terminal.html")
    if not html_file.exists():
        print("❌ ai-terminal.html not found")
        return False
    
    content = html_file.read_text(encoding='utf-8')
    
    # Add CDN fallback script
    fallback_script = """
    <script>
    // CDN fallback for xterm.js
    if (typeof Terminal === 'undefined') {
        console.log('Loading xterm.js fallback...');
        var script = document.createElement('script');
        script.src = '/static/js/xterm.min.js';
        script.onload = function() {
            console.log('Xterm.js fallback loaded');
        };
        document.head.appendChild(script);
        
        var link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = '/static/css/xterm.css';
        document.head.appendChild(link);
    }
    </script>
"""
    
    # Insert before closing body tag
    if "</body>" in content:
        content = content.replace("</body>", f"{fallback_script}\n</body>")
        html_file.write_text(content, encoding='utf-8')
        print("✓ Added CDN fallback script")
        return True
    
    return False

def create_systemd_service():
    """Create systemd service for the application"""
    service_content = """
[Unit]
Description=AI-Powered SSH Terminal
After=network.target

[Service]
Type=simple
User=ai-terminal
Group=ai-terminal
WorkingDirectory=/opt/ai-terminal
Environment=PATH=/opt/ai-terminal/venv/bin
Environment=AI_TERMINAL_ENV=production
ExecStart=/opt/ai-terminal/venv/bin/python app.py
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=5

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/ai-terminal/data

[Install]
WantedBy=multi-user.target
"""
    
    return service_content

def deploy_to_directory(target_dir, optimize=True):
    """Deploy frontend to a specific directory"""
    print(f"📁 Deploying to {target_dir}")
    
    target_path = Path(target_dir)
    target_path.mkdir(parents=True, exist_ok=True)
    
    # Copy main files
    files_to_copy = [
        "ai-terminal.html",
        "README.md",
        "FRONTEND_GUIDE.md"
    ]
    
    for file_name in files_to_copy:
        file_path = Path(file_name)
        if file_path.exists():
            shutil.copy2(file_path, target_path)
            print(f"✓ Copied {file_name}")
    
    # Create static directory
    static_dir = target_path / "static"
    static_dir.mkdir(exist_ok=True)
    
    # Copy static assets if they exist
    if Path("static").exists():
        shutil.copytree("static", static_dir, dirs_exist_ok=True)
    
    if optimize:
        optimize_static_files(static_dir)
    
    print(f"✅ Frontend deployed to {target_dir}")

def create_monitoring_dashboard():
    """Create a simple monitoring dashboard"""
    dashboard_html = """
<!DOCTYPE html>
<html>
<head>
    <title>AI Terminal - Monitoring</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; background: #f5f5f5; }
        .dashboard { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; }
        .card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        .metric { font-size: 24px; font-weight: bold; color: #2196F3; }
        .status-good { color: #4CAF50; }
        .status-warning { color: #FF9800; }
        .status-error { color: #F44336; }
        .refresh-btn { background: #2196F3; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; }
    </style>
</head>
<body>
    <h1>🤖 AI Terminal - System Monitoring</h1>
    
    <button class="refresh-btn" onclick="refreshData()">🔄 Refresh</button>
    
    <div class="dashboard">
        <div class="card">
            <h3>Service Status</h3>
            <div id="service-status" class="metric status-good">✅ Running</div>
            <p>Backend server operational</p>
        </div>
        
        <div class="card">
            <h3>Active Connections</h3>
            <div id="active-connections" class="metric">0</div>
            <p>Current SSH sessions</p>
        </div>
        
        <div class="card">
            <h3>AI Model Status</h3>
            <div id="ai-status" class="metric status-good">✅ Available</div>
            <p>Local LLaMA model</p>
        </div>
        
        <div class="card">
            <h3>Memory Usage</h3>
            <div id="memory-usage" class="metric">--</div>
            <p>System memory consumption</p>
        </div>
        
        <div class="card">
            <h3>Uptime</h3>
            <div id="uptime" class="metric">--</div>
            <p>Service availability</p>
        </div>
        
        <div class="card">
            <h3>Last Error</h3>
            <div id="last-error" class="metric">None</div>
            <p>Recent error messages</p>
        </div>
    </div>
    
    <script>
        async function refreshData() {
            try {
                const response = await fetch('/api/monitoring/stats');
                if (response.ok) {
                    const data = await response.json();
                    updateDashboard(data);
                } else {
                    document.getElementById('service-status').innerHTML = '❌ Error';
                    document.getElementById('service-status').className = 'metric status-error';
                }
            } catch (error) {
                console.error('Failed to fetch monitoring data:', error);
                document.getElementById('service-status').innerHTML = '❌ Offline';
                document.getElementById('service-status').className = 'metric status-error';
            }
        }
        
        function updateDashboard(data) {
            document.getElementById('active-connections').textContent = data.activeConnections || 0;
            document.getElementById('memory-usage').textContent = (data.memoryUsage || 0) + ' MB';
            document.getElementById('uptime').textContent = data.uptime || '--';
            document.getElementById('last-error').textContent = data.lastError || 'None';
            
            // Update AI status
            const aiStatus = document.getElementById('ai-status');
            if (data.aiModelLoaded) {
                aiStatus.innerHTML = '✅ Available';
                aiStatus.className = 'metric status-good';
            } else {
                aiStatus.innerHTML = '⚠️ Template Mode';
                aiStatus.className = 'metric status-warning';
            }
        }
        
        // Auto-refresh every 30 seconds
        setInterval(refreshData, 30000);
        
        // Initial load
        refreshData();
    </script>
</body>
</html>
"""
    
    return dashboard_html

def main():
    """Main deployment function"""
    parser = argparse.ArgumentParser(description='Deploy AI Terminal Frontend')
    parser.add_argument('--type', choices=['nginx', 'docker', 'directory', 'systemd'], 
                       default='directory', help='Deployment type')
    parser.add_argument('--target', default='./deployment', 
                       help='Target directory for deployment')
    parser.add_argument('--domain', default='localhost', 
                       help='Domain name for nginx configuration')
    parser.add_argument('--ssl', action='store_true', 
                       help='Enable SSL configuration')
    parser.add_argument('--optimize', action='store_true', default=True,
                       help='Optimize static files')
    parser.add_argument('--monitoring', action='store_true',
                       help='Create monitoring dashboard')
    
    args = parser.parse_args()
    
    print("🚀 AI Terminal Frontend Deployment")
    print("=" * 40)
    
    if args.type == 'nginx':
        # Create Nginx configuration
        config = create_nginx_config(args.domain, args.ssl)
        config_file = Path(args.target) / 'nginx.conf'
        config_file.parent.mkdir(parents=True, exist_ok=True)
        config_file.write_text(config)
        print(f"✅ Nginx configuration created: {config_file}")
        
    elif args.type == 'docker':
        # Create Docker configuration
        dockerfile, docker_compose = create_docker_config()
        
        Path(args.target).mkdir(parents=True, exist_ok=True)
        (Path(args.target) / 'Dockerfile.frontend').write_text(dockerfile)
        (Path(args.target) / 'docker-compose.frontend.yml').write_text(docker_compose)
        
        print(f"✅ Docker configuration created in {args.target}")
        
    elif args.type == 'systemd':
        # Create systemd service
        service_content = create_systemd_service()
        service_file = Path(args.target) / 'ai-terminal.service'
        service_file.parent.mkdir(parents=True, exist_ok=True)
        service_file.write_text(service_content)
        print(f"✅ Systemd service created: {service_file}")
        
    elif args.type == 'directory':
        # Deploy to directory
        deploy_to_directory(args.target, args.optimize)
    
    # Add monitoring dashboard if requested
    if args.monitoring:
        dashboard = create_monitoring_dashboard()
        dashboard_file = Path(args.target) / 'monitoring.html'
        dashboard_file.write_text(dashboard)
        print(f"✅ Monitoring dashboard created: {dashboard_file}")
    
    # Setup CDN fallback
    if setup_cdn_fallback():
        print("✅ CDN fallback configured")
    
    print("\n📋 Deployment Complete!")
    print(f"📁 Files location: {args.target}")
    print("📖 See FRONTEND_GUIDE.md for detailed usage instructions")
    
    if args.type == 'nginx':
        print(f"🔧 Copy nginx.conf to /etc/nginx/sites-available/{args.domain}")
        print(f"🔗 Enable with: ln -s /etc/nginx/sites-available/{args.domain} /etc/nginx/sites-enabled/")
    
    elif args.type == 'systemd':
        print("🔧 Install service with:")
        print(f"   sudo cp {args.target}/ai-terminal.service /etc/systemd/system/")
        print("   sudo systemctl daemon-reload")
        print("   sudo systemctl enable ai-terminal")
        print("   sudo systemctl start ai-terminal")

if __name__ == "__main__":
    main()